﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Publicuse.Util
{
    public class DistanceUtil
    {

        /// <summary>
        /// 输入亮点之间的坐标计算出大概价格
        /// 根据《通知》，今后广州全市出租车运价将实行同城同价，具体标准为：
        /// 起步价：首3公里12元道;
        /// 续租专价：超过3公里部分，每公里2.6元;
        /// 候时费：巡游车营运时速低于10公里，每小时44元;
        /// 返空费实行阶梯附加，15至25公里按照续租价加收20%，25公里以上按续租价加收50%;
        /// 增设夜间服务费(23：00-次日5：00)，按续租价加收30%。
        /// </summary>
        /// <param name="lat1"></param>
        /// <param name="lon1"></param>
        /// <param name="lat2"></param>
        /// <param name="lon2"></param>
        /// <returns></returns>
        public static decimal CalculatePrice(string lat1, string lon1, string lat2, string lon2)
        {
            //起步价
            double price = 12;
            //计算出两点之间的距离
            double len = Distance(Convert.ToDouble(lat1), Convert.ToDouble(lon1), Convert.ToDouble(lat2), Convert.ToDouble(lon2));
            if (len > 3 && len < 15)
            {
                //低于15公里的计算方法
                price += (len - 3) * 2.6;
            }
            else if (len >= 15 && len < 25)
            {
                //大于15公里小于25公里的计算方法
                price += (12 * 2.6) + ((len - 15) * 2.6 * 1.2);
            }
            else if (len >= 25)
            {
                //大于25公里的计算方法
                price += (12 * 2.6) + (10 * 2.6 * 1.2) + ((len - 25) * 2.6 * 1.5);
            }
            return Convert.ToDecimal(price);
        }


        static double EARTH_RADIUS = 6371.0;//km 地球半径 平均值，千米
        /// <summary>
        /// 给定的经度1，纬度1；经度2，纬度2. 计算2个经纬度之间的距离。
        /// </summary>
        /// <param name="lat1">经度1</param>
        /// <param name="lon1">纬度1</param>
        /// <param name="lat2">经度2</param>
        /// <param name="lon2">纬度2</param>
        /// <returns>距离（公里、千米）</returns>
        public static double Distance(double lat1, double lon1, double lat2, double lon2)
        {
            //用haversine公式计算球面两点间的距离。
            //经纬度转换成弧度
            lat1 = ConvertDegreesToRadians(lat1);
            lon1 = ConvertDegreesToRadians(lon1);
            lat2 = ConvertDegreesToRadians(lat2);
            lon2 = ConvertDegreesToRadians(lon2);

            //差值
            var vLon = Math.Abs(lon1 - lon2);
            var vLat = Math.Abs(lat1 - lat2);

            //h is the great circle distance in radians, great circle就是一个球体上的切面，它的圆心即是球心的一个周长最大的圆。
            var h = HaverSin(vLat) + Math.Cos(lat1) * Math.Cos(lat2) * HaverSin(vLon);

            var distance = 2 * EARTH_RADIUS * Math.Asin(Math.Sqrt(h));

            return distance;
        }

        /// <summary>
        /// 将角度换算为弧度。
        /// </summary>
        /// <param name="degrees">角度</param>
        /// <returns>弧度</returns>
        public static double ConvertDegreesToRadians(double degrees)
        {
            return degrees * Math.PI / 180;
        }

        public static double HaverSin(double theta)
        {
            var v = Math.Sin(theta / 2);
            return v * v;
        }
    }
}
